package com.kitten.count.consumer.comment;

import cn.hutool.core.collection.CollUtil;
import com.github.phantomthief.collection.BufferTrigger;
import com.kitten.count.constant.MQConstants;
import com.kitten.count.domain.mapper.NoteCountDOMapper;
import com.kitten.count.model.dto.comment.CountCommentPublishMqDTO;
import com.kitten.framework.common.utils.JsonUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author kitten
 */
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "kitten_group_" + MQConstants.TOPIC_COUNT_COMMENT,
    topic = MQConstants.TOPIC_COUNT_COMMENT
)
public class CountNoteCommentConsumer implements RocketMQListener<String> {

    @Resource
    private NoteCountDOMapper noteCountDOMapper;

    private BufferTrigger<String> bufferTrigger = BufferTrigger.<String>batchBlocking()
            .bufferSize(50000) // 缓存队列的最大容量
            .batchSize(1000)   // 一批次最多聚合 1000 条
            .linger(Duration.ofSeconds(1)) // 多久聚合一次（1s 一次）
            .setConsumerEx(this::consumeMessage) // 设置消费者方法
            .build();

    @Override
    public void onMessage(String s) {
        bufferTrigger.enqueue(s);
    }

    private void consumeMessage(List<String> bodys) {
        log.info("聚合消息, size: {}", bodys.size());
        List<CountCommentPublishMqDTO> mqDTOList = Lists.newArrayList();
        bodys.forEach(body -> {
            try {
                List<CountCommentPublishMqDTO> list = JsonUtils.parseList(body, CountCommentPublishMqDTO.class);
                mqDTOList.addAll(list);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        // 按笔记 ID 进行分组
        Map<Long, List<CountCommentPublishMqDTO>> groupMap = mqDTOList.stream()
                .collect(Collectors.groupingBy(CountCommentPublishMqDTO::getNoteId));

        // 循环分组字典
        for (Map.Entry<Long, List<CountCommentPublishMqDTO>> entry : groupMap.entrySet()) {
            // 笔记 ID
            Long noteId = entry.getKey();
            // 评论数
            int count = CollUtil.size(entry.getValue());

            // 若评论数大于零，则执行更新操作：累加评论总数
            if (count > 0) {
                noteCountDOMapper.insertOrUpdateCommentTotalByNoteId(count, noteId);
            }
        }

    }

}
